﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Drawing;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Threading;
using System.Web;
using System.Web.Mvc;
using DevExpress.XtraPrinting;
using DevExpress.XtraReports.Parameters;
using DevExpress.XtraReports.UI;
using DxMvcApplication.Areas.Administrator.Models;
using DxMvcApplication.Repositories.Core.Security;
using DxMvcApplication.Repositories.Implementations.Security;
using ReportHelper.BuCA;

namespace DxMvcApplication.Areas.Administrator.Controllers.Report
{
    public class BaseReportController : Controller
    {
        //private readonly DbOptionRepository _dbOptionRepository;
        //private readonly UnitRepository _unitRepository;

        #region variables

        protected MemoryStream Stream;
        protected XtraReport Report;
        public string ReportTitle { get; set; }
        public string ReportTitleDate { get; set; }
        public string OwnerCompanyName { get; set; }
        public string CompanyName { get; set; }
        public string CompanyAddress { get; set; }
        public string ReportTemplateNo { get; set; }
        public string DirectoryTitle { get; set; }
        public string DirectoryTitleNoteText { get; set; }
        public string DirectoryName { get; set; }
        public string ChiefAccountantTitle { get; set; }
        public string ChiefAccountantTitleNoteText { get; set; }
        public string ChiefAccountantName { get; set; }
        public string CashierTitle { get; set; }
        public string CashierTitleNoteText { get; set; }
        public string CashierName { get; set; }
        public string ProductName { get; set; }
        public string PrintDate { get; set; }
        public static string ControllerName { get; set; }
        public string ReportSession { get; set; }
        public IList DataSource { get; set; }
        protected bool AutoAddReportHeader = true;
        protected bool AutoAddReportFooter = false;
        protected bool UsingCachingToLoadData = false;
        protected SortedList Parameters;
        public DateTime FromDate { get; set; }
        public DateTime Todate { get; set; }
        public string PromulgateInfo { get; set; }
        public string PromulgateInfo1 { get; set; }
        public bool PrintLicenseInfo { get; set; }
        public bool PrintPromulgateInfo { get; set; }
        public bool IsPrintDictionary = false;
        protected bool UsingParameter = false;
        public string BudgetUnitCode { get; set; }
        public bool IsPrintAccountingMode = false;
        public DateTime PostDate { get; set; }
        public long UnitId { get; set; }

        private readonly ISiteRepository _siteRepository;
        #endregion

        private string _unitName;
        //public BaseReportController()
        //{
        //    _siteRepository=new SiteRepository();
        //}

        /// <summary>
        /// Indexes the specified site identifier.
        /// </summary>
        /// <param name="siteId">The site identifier.</param>
        /// <returns></returns>
        public virtual ActionResult Index(int? siteId = 0)
        {
            if (siteId > 0)
            {
                var obj = _siteRepository.Get((int)siteId);
                return View(obj.ToModel());
            }
            return View("Error");
        }

        protected override void OnActionExecuting(ActionExecutingContext filterContext)
        {
            var unitIdSession = Session["UnitId"];            
            if (unitIdSession == null || (long)unitIdSession == 0)
                filterContext.Result = RedirectToAction("Logout", "Auth", new { @returnUrl = Request.RawUrl });
            else
            {
                var sesionName = Session["UnitName"];
                _unitName = sesionName != null ? sesionName.ToString() : "";
                base.OnActionExecuting(filterContext);
            }
        }
        public BaseReportController()
        {
            //_dbOptionRepository = new DbOptionRepository();
            //_unitRepository = new UnitRepository();
            //var unit = _unitRepository.Get(int.Parse(System.Web.HttpContext.Current.Session["FA-BigTime.UnitId"].ToString())).ToModel();
            _siteRepository = new SiteRepository();
            //---Get value from database to common variables here---//
            CompanyName = "FPT";//unit == null ? "Tên đơn vị: " : "Tên đơn vị: " + unit.UnitName;
            CompanyAddress = "Cầu Giấy";//unit == null ? "Không có đơn vị chủ quản" : "Đơn vị chủ quản: " + unit.ByManagement;
            BudgetUnitCode = "HaNoi";//unit == null ? "Không có mã quan hệ ngân sách" : "Mã đơn vị có quan hệ với ngân sách: " + unit.BudgetCode;
            ReportTemplateNo = "Biểu số 01";
            //PromulgateInfo = "(Ban hành kèm theo Thông tư số 89/2010/TT/BTC//nngày 16/6/2010 của Bộ Tài chính)";
            PromulgateInfo = "";
            PromulgateInfo1 = "";

            FromDate = new DateTime(DateTime.Now.Year, 1, 1);
            Todate = new DateTime(DateTime.Now.Year, 12, 31);
            ReportTitleDate = DateToWord.ReadDate(FromDate, Todate);
            //var options = _dbOptionRepository.GetList().ToModel();

            PrintDate = "Hà Nội, ngày " + DateTime.Now.Day + " tháng " + DateTime.Now.Month + " năm " + DateTime.Now.Year;

            DirectoryTitle = "Thủ trưởng đơn vị";
            DirectoryTitleNoteText = "(Ký, đóng dấu và họ tên)";
            DirectoryName = "ThoDD";//options != null ? (from option in options where option.OptionCode == "UnitDirector" select option.OptionValue).First() : null;

            ChiefAccountantTitle = "Kế toán trưởng";
            ChiefAccountantTitleNoteText = "(Ký và ghi rõ họ tên)";
            ChiefAccountantName = "TuanHM"; //options != null ? (from option in options where option.OptionCode == "UnitChiefAccountant" select option.OptionValue).First() : null;

            CashierTitle = "Người lập biểu";
            CashierTitleNoteText = "(Ký và ghi rõ họ tên)";
            CashierName = "SonHB";//options != null ? (from option in options where option.OptionCode == "UnitReportPreparer" select option.OptionValue).First() : null;
            //and Currency format, number format, Font, ...
            Parameters = new SortedList { { "FromDate", FromDate }, { "ToDate", Todate }, { "UnitID", "" } };

            var cInfo = new CultureInfo("vi-VN")
            {
                NumberFormat =
                {
                    CurrencySymbol = "",
                    CurrencyDecimalDigits = 0
                }
            };
            Thread.CurrentThread.CurrentCulture = cInfo;
        }

        protected virtual void SetParameter(XtraReport xtraReport)
        {
            var paraCompanyName = new Parameter { Name = "CompanyName", Value = CompanyName };
            var paraCompanyAddress = new Parameter { Name = "CompanyAddress", Value = CompanyAddress };
            var paraBudgetUnitCode = new Parameter { Name = "BudgetUnitCode", Value = BudgetUnitCode };
            var paraDirectoryName = new Parameter { Name = "DirectoryName", Value = DirectoryName };
            var paraChiefAccountantName = new Parameter { Name = "ChiefAccountantName", Value = ChiefAccountantName };
            var paraCashierName = new Parameter { Name = "CashierName", Value = CashierName };
            var paraOwnerCompanyName = new Parameter { Name = "OwnerCompanyName", Value = OwnerCompanyName };
            var paraReportTitle = new Parameter { Name = "ReportTitle", Value = ReportTitle };
            var paraProductName = new Parameter { Name = "ProductName", Value = ProductName };
            Report.Parameters.AddRange(new[] { paraCompanyName, paraCompanyAddress, paraBudgetUnitCode, paraDirectoryName, 
                paraChiefAccountantName, paraCashierName ,paraOwnerCompanyName,paraReportTitle,paraProductName});
        }

        protected virtual ReportHeaderBand CreateReportHeaderBand()
        {
            var reportHeader = new ReportHeaderBand();
            var xrReportHeaderTable = new XRTable
            {
                Name = "LicenseInfo",
                WidthF = Report.Bands[BandKind.Detail].Controls[0].WidthF,
                //Borders = BorderSide.All
            };

            /*Row*/
            var row1 = new XRTableRow();
            var row2 = new XRTableRow();
            var row3 = new XRTableRow();

            /*Cell*/
            //--------------------------------------------
            var xrCellCompanyName = new XRTableCell
            {
                Text = CompanyName,
                Font = new Font("Tahoma", 10, FontStyle.Bold),
            };
            var xrCellCompanyAddress = new XRTableCell
            {
                Text = CompanyAddress,
                Font = new Font("Tahoma", 10, FontStyle.Regular),
            };
            var xrCellBudgetUnitCode = new XRTableCell
            {
                Text = BudgetUnitCode,
                Font = new Font("Tahoma", 10, FontStyle.Regular),
            };

            var xrReportHeaderTemplateNo = new XRTableCell
            {
                Text = ReportTemplateNo,
                Font = new Font("Tahoma", 10, FontStyle.Bold),
                TextAlignment = TextAlignment.MiddleCenter,
                Width = GetWidhOfText(PromulgateInfo, new Font("Tahoma", 10, FontStyle.Bold)) + 10
            };

            var xrCellPromulgateInfo = new XRTableCell
            {
                Text = PromulgateInfo,
                Font = new Font("Tahoma", 10, FontStyle.Italic),
                TextAlignment = TextAlignment.MiddleCenter,
                Multiline = true,
                Width = GetWidhOfText(PromulgateInfo, new Font("Tahoma", 10, FontStyle.Bold)) + 10
            };
            var xrCellPromulgateInfo1 = new XRTableCell
            {
                Text = PromulgateInfo1,
                Font = new Font("Tahoma", 10, FontStyle.Italic),
                TextAlignment = TextAlignment.MiddleCenter,
                Multiline = true,
                Width = GetWidhOfText(PromulgateInfo, new Font("Tahoma", 10, FontStyle.Bold)) + 10
            };

            xrCellPromulgateInfo.BeforePrint += CellPromulgateInfo_BeforePrint;

            if (IsPrintDictionary)
            {
                row1.Cells.AddRange(new[] { xrCellCompanyName });
                row2.Cells.AddRange(new[] { xrCellCompanyAddress });
            }
            else
            {
                if (IsPrintAccountingMode)
                {
                    row1.Cells.AddRange(new[] { xrCellCompanyName, xrReportHeaderTemplateNo });
                    row2.Cells.AddRange(new[] { xrCellCompanyAddress, xrCellPromulgateInfo });
                    row3.Cells.AddRange(new[] { xrCellBudgetUnitCode, xrCellPromulgateInfo1 });
                }
                else
                {
                    row1.Cells.AddRange(new[] { xrCellCompanyName, xrReportHeaderTemplateNo });
                    row2.Cells.AddRange(new[] { xrCellCompanyAddress, xrCellPromulgateInfo });
                }
            }

            xrReportHeaderTable.Rows.AddRange(new[] { row1, row2, row3 });

            var xrReportTitleLable = new XRLabel
            {
                Text = ReportTitle.ToUpper(),
                TextAlignment = TextAlignment.MiddleCenter,
                Width = Report.PageWidth - (Report.Margins.Left + Report.Margins.Right),
                Location = new Point(0, xrReportHeaderTable.Location.Y + 40),
                WordWrap = true,
                Font = new Font("Times New Roman", 14, FontStyle.Bold),
            };

            var xrReportDateLable = new XRLabel
            {
                Text = ReportTitleDate,
                TextAlignment = TextAlignment.MiddleCenter,
                Width = Report.PageWidth - (Report.Margins.Left + Report.Margins.Right),
                Location = new Point(0, xrReportTitleLable.Location.Y + 25),
                WordWrap = true,
                Font = new Font("Times New Roman", 10, FontStyle.Regular)
            };

            reportHeader.Controls.AddRange(new XRControl[] { xrReportHeaderTable, xrReportTitleLable, xrReportDateLable });
            return reportHeader;
        }

        private void CellPromulgateInfo_BeforePrint(object sender, System.Drawing.Printing.PrintEventArgs e)
        {
            ((XRTableCell)sender).Text = ((XRTableCell)sender).Text.Replace("\\n", Environment.NewLine);
        }

        private int GetWidhOfText(string text, XRTableCell cell)
        {
            int factor;
            Graphics gr = Graphics.FromHwnd(IntPtr.Zero);
            if (Report.ReportUnit == ReportUnit.HundredthsOfAnInch)
            {
                gr.PageUnit = GraphicsUnit.Inch;
                factor = 100;
            }
            else
            {
                gr.PageUnit = GraphicsUnit.Millimeter;
                factor = 10;
            }
            var textValue = text.Replace("\\n", Environment.NewLine);
            string[] splitText = textValue.Split(new[] { '\n' });
            var maxVal = splitText.Max(x => x.Length);
            var str = splitText.First(x => x.Length == maxVal);

            SizeF size = gr.MeasureString(str, cell.Font);
            int width = Convert.ToInt32(size.Width * factor);
            gr.Dispose();
            return width;
        }

        private int GetWidhOfText(string text, Font font)
        {
            int factor;
            Graphics gr = Graphics.FromHwnd(IntPtr.Zero);
            if (Report.ReportUnit == ReportUnit.HundredthsOfAnInch)
            {
                gr.PageUnit = GraphicsUnit.Inch;
                factor = 100;
            }
            else
            {
                gr.PageUnit = GraphicsUnit.Millimeter;
                factor = 10;
            }
            var textValue = text.Replace("\\n", Environment.NewLine); ;
            string[] splitText = textValue.Split(new[] { '\n' });
            var maxVal = splitText.Max(x => x.Length);
            var str = splitText.First(x => x.Length == maxVal);

            SizeF size = gr.MeasureString(str, font);
            int width = Convert.ToInt32(size.Width * factor);
            gr.Dispose();
            return width / 10;
        }

        protected virtual ReportFooterBand CreateReportFooterBand()
        {
            //Check ReportFooterBand existed
            ReportFooterBand reportFooter;

            if (Report.Bands[BandKind.ReportFooter] != null)
            {
                reportFooter = (ReportFooterBand)Report.Bands[BandKind.ReportFooter];
            }
            else
            {
                //Add Report Footer
                reportFooter = new ReportFooterBand();
            }

            var xrTableFooter = new XRTable { Width = Report.Bands[BandKind.Detail].Controls[0].Width, Height = 120 };
            /*Row*/
            var xrTableRowPrintDate = new XRTableRow();
            var xrTableRowSignatureTitle = new XRTableRow();
            var xrTableRowSignatureNoteTitle = new XRTableRow();
            var xrTableTopRowSpace = new XRTableRow { Height = 30 };
            var xrTableMidRowSpace = new XRTableRow { Height = 200 };
            var xrTableRowSignatureName = new XRTableRow();
            /*Cell*/
            //--------------------------------------------
            var xrCellPrintDate = new XRTableCell
            {
                Text = PrintDate,
                Font = new Font("Times New Roman", 10, FontStyle.Italic),
                TextAlignment = TextAlignment.MiddleCenter
            };

            var xrCellDirectoryTitle = new XRTableCell
            {
                Text = DirectoryTitle,
                Font = new Font("Times New Roman", 11, FontStyle.Bold),
                TextAlignment = TextAlignment.MiddleCenter
            };
            var xrCellDirectoryName = new XRTableCell
            {
                Text = DirectoryName,
                Font = new Font("Times New Roman", 11, FontStyle.Regular),
                TextAlignment = TextAlignment.MiddleCenter
            };

            var xrCellDirectoryTitleNoteText = new XRTableCell
            {
                Font = new Font("Times New Roman", 10, FontStyle.Regular),
                Text = DirectoryTitleNoteText,
                TextAlignment = TextAlignment.MiddleCenter
            };
            var xrCellChiefAccountantTitle = new XRTableCell
            {
                Text = ChiefAccountantTitle,
                Font = new Font("Times New Roman", 11, FontStyle.Bold),
                TextAlignment = TextAlignment.MiddleCenter
            };
            var xrCellChiefAccountantName = new XRTableCell
            {
                Text = ChiefAccountantName,
                Font = new Font("Times New Roman", 11, FontStyle.Regular),
                TextAlignment = TextAlignment.MiddleCenter
            };
            var xrCellChiefAccountantTitleNoteText = new XRTableCell
            {
                Text = ChiefAccountantTitleNoteText,
                Font = new Font("Times New Roman", 10, FontStyle.Regular),
                TextAlignment = TextAlignment.MiddleCenter
            };

            var xrCellCashierTitle = new XRTableCell
            {
                Text = CashierTitle,
                Font = new Font("Times New Roman", 11, FontStyle.Bold),
                TextAlignment = TextAlignment.MiddleCenter
            };
            var xrCellCashierName = new XRTableCell
            {
                Text = CashierName,
                Font = new Font("Times New Roman", 11, FontStyle.Regular),
                TextAlignment = TextAlignment.MiddleCenter
            };
            var xrCellCashierTitleNoteText = new XRTableCell
            {
                Text = CashierTitleNoteText,
                Font = new Font("Times New Roman", 10, FontStyle.Regular),
                TextAlignment = TextAlignment.MiddleCenter
            };

            xrTableRowPrintDate.Cells.AddRange(new[] { new XRTableCell(), new XRTableCell(), xrCellPrintDate });
            xrTableRowSignatureTitle.Cells.AddRange(new[] { xrCellCashierTitle, xrCellChiefAccountantTitle, xrCellDirectoryTitle });
            xrTableRowSignatureNoteTitle.Cells.AddRange(new[] { xrCellCashierTitleNoteText, xrCellChiefAccountantTitleNoteText, xrCellDirectoryTitleNoteText });

            xrTableRowSignatureName.Cells.AddRange(new[] { xrCellCashierName, xrCellChiefAccountantName, xrCellDirectoryName });

            xrTableFooter.Rows.AddRange(new[] { xrTableTopRowSpace, xrTableRowPrintDate, xrTableRowSignatureTitle, xrTableRowSignatureNoteTitle, xrTableMidRowSpace, xrTableRowSignatureName });

            if (Report.Bands[BandKind.ReportFooter] != null)
            {
                xrTableFooter.Location = new Point(Report.Bands[BandKind.ReportFooter].Controls[0].Location.X, Report.Bands[BandKind.ReportFooter].Controls[0].Location.Y + 30);
            }

            reportFooter.Controls.Add(xrTableFooter);
            xrTableFooter.KeepTogether = true;
            return reportFooter;
        }

        protected virtual PageFooterBand CreatePageFooterBand()
        {
            var pageFooterBand = new PageFooterBand { Name = "Footer", Height = 10 };
            var xrTablePageFooter = new XRTable { Width = Report.Bands[BandKind.Detail].Controls[0].Width };
            /*Row*/
            var xrTableRowPageFooter = new XRTableRow
            {
                Width = Report.Bands[BandKind.Detail].Controls[0].Width,
                Name = "PageFooterInfo"
            };
            /*Cell*/
            //--------------------------------------------
            var xrPageInfo = new XRPageInfo
            {
                Name = "PageInfo",
                Format = "TRANG {0}",
                ForeColor = Color.DarkGray,
                TextAlignment = TextAlignment.MiddleRight
            };
            var xrCellPageInfo = new XRTableCell
            {
                Font = new Font("Times New Roman", 7, FontStyle.Regular),
                TextAlignment = TextAlignment.MiddleRight
            };

            var xrCellProductName = new XRTableCell
            {
                Name = "ProductName",
                Text = "FA-BIGTIME ",
                Font = new Font("Times New Roman", 7, FontStyle.Regular),
                ForeColor = Color.DarkGray,
                TextAlignment = TextAlignment.MiddleLeft,
                Width = Report.Bands[BandKind.Detail].Controls[0].Width - 100
            };

            xrCellPageInfo.Controls.Add(xrPageInfo);
            xrTableRowPageFooter.Cells.AddRange(new XRControl[] { xrCellProductName, xrCellPageInfo });
            xrTablePageFooter.Rows.AddRange(new[] { xrTableRowPageFooter });
            pageFooterBand.Controls.Add(xrTablePageFooter);
            return pageFooterBand;
        }

        public virtual XtraReport CreateReport(XtraReport xtraReport)
        {
            if (AutoAddReportHeader)
            {
                ReportHeaderBand reportHeader = CreateReportHeaderBand();
                reportHeader.Controls["LicenseInfo"].Location = new Point(xtraReport.Bands[BandKind.Detail].Controls[0].Location.X, 0);
                Report.Bands.Add(reportHeader);
            }
            if (AutoAddReportFooter)
            {
                ReportFooterBand reportFooter = CreateReportFooterBand();
                Report.Bands.Add(reportFooter);

            }

            PageFooterBand pageFooterBand = CreatePageFooterBand();
            pageFooterBand.Controls[0].Location = new Point(xtraReport.Bands[BandKind.Detail].Controls[0].Location.X, 0);
            pageFooterBand.Controls[0].Width = xtraReport.Bands[BandKind.Detail].Controls[0].Width;
            Report.Bands.Add(pageFooterBand);

            if (!AutoAddReportHeader || !AutoAddReportFooter)
            {
                SetParameter(xtraReport);
            }
            if (!UsingCachingToLoadData)
            {
                if (DataSource == null)
                {
                    Report.DataSourceDemanded += Report_DataSourceDemanded;
                }
            }
            #region "Dùng trong trường hợp dữ liệu lớn"
            //else
            //{
            //    //----------------------------------------------------------------
            //    Report.DataSourceDemanded += (s, e) =>
            //                                     {
            //                                         var repository = new Repository();
            //                                         ((XtraReport)s).DataSource = DataSource ??
            //                                                                       repository.Query<T>().ToList();
            //                                     };

            //    if (Session[ReportSession] == null)
            //    {
            //        Report.CreateDocument();
            //        MS = new MemoryStream();
            //        PrintingSystemAccessor.SaveIndependentPages(Report.PrintingSystem, MS);
            //        Session[ReportSession] = MS;
            //    }
            //    else
            //    {
            //        MS = (MemoryStream)Session[ReportSession];
            //        PrintingSystemAccessor.LoadVirtualDocument(Report.PrintingSystem, MS);
            //    }
            //    //----------------------------------------------------------------
            //}
            #endregion
            return Report;
        }

        public virtual void Report_DataSourceDemanded(object sender, EventArgs e)
        {
        }

        public virtual XtraReport GetReport()
        {
            return new XtraReport();
        }

        public virtual XtraReport GetReport(Models.Report.ReportCriteria criteria)
        {
            return new XtraReport();
        }

        public ActionResult ReportViewer(Models.Report.ReportCriteria criteria)
        {
            ViewBag.Message = "Hệ thống quản lý Tài sản cố định FA-BigTime 2014!";
            Report = CreateReport(GetReport(criteria));
            ViewData["Report"] = Report;
            Session["Report"] = Report;

            return PartialView(model: ControllerName);
        }

        public ActionResult ReportViewerPartial(Models.Report.ReportCriteria criteria)
        {
            ViewData["Report"] = Session["Report"];
            return PartialView("ReportViewerPartial", ControllerName);
        }

        public virtual ActionResult ExportReportViewer()
        {
            return DevExpress.Web.Mvc.ReportViewerExtension.ExportTo((XtraReport)Session["Report"]);
        }
    }
}